package com.tanhua.dubbo.server.service;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import com.tanhua.common.exception.UnauthorizedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

/**
 * Created with IntelliJ IDEA.
 *
 * @ClassName: RequestService
 * @Author:王晨晗
 * @Description: 环信平台的相关请求的操作
 * @Date: 2022/01/05/16:56
 */
@Service
@Slf4j
public class RequestService {
    @Autowired
    private TokenService tokenService;

    /**
     * @description 环信平台通用请求方式
     * @param url      请求地址
     * @param body     请求参数
     * @param method   请求方法
     * @return
     */
    @Retryable(value = UnauthorizedException.class , maxAttempts = 5 , backoff = @Backoff(delay = 2000L , multiplier = 2))
    public HttpResponse execute(String url , String body , Method method){
        //获取环信平台token
        String token = tokenService.getToken();

        //判断请求方式
        HttpRequest httpRequest;
        switch (method) {
            case POST: {
                httpRequest = HttpRequest.post(url);
                break;
            }
            case DELETE: {
                httpRequest = HttpRequest.delete(url);
                break;
            }
            case PUT: {
                httpRequest = HttpRequest.put(url);
                break;
            }
            case GET: {
                httpRequest = HttpRequest.get(url);
                break;
            }
            default: {
                return null;
            }
        }

        //发送请求.获取响应
        HttpResponse response = httpRequest
                .header("Content-type", "application/json")        //设置请求内容的类型
                .header("Authorization", "Bearer " + token)        //设置token
                .body(body)         //设置请求数据
                .timeout(20000)     //设置超时时间
                .execute();//执行请求

        // 判断响应状态
        if (response.getStatus() == 401){
            //token失效,刷新token
            tokenService.refreshToken();
            //抛出异常,执行重试
            throw new UnauthorizedException();
        }

        return response;
    }

    /**
     * @description 全部重试失败后执行
     * @param e
     * @return
     */
    @Recover
    public HttpResponse recover(UnauthorizedException e){
        log.error("获取token失败! url= " + e.getUrl() + ", body= " + e.getBody() + ",method = " + e.getMethod().toString());
        //重试五次,依旧获取不到token , 说明网络/账号出现了问题, 只能返回null
        return null;
    }
}
